<template>
  <!-- <transition name="el-zoom-in-center"> -->
  <div class="JNPF-preview-main flow-form-main">
    <div class="JNPF-common-page-header">
      <div v-if="setting.fromForm || isFromOaJump">{{title}}</div>
      <el-page-header @back="goBack" v-else>
        <template slot="content">
          <div class="JNPF-page-header-content">{{title}}</div>
        </template>
      </el-page-header>
      <template v-if="!loading||title">
        <el-dropdown placement="bottom" @command="handleFlowUrgent" trigger="click" v-show="setting.opType=='-1'">
          <div class="flow-urgent-value" style="cursor:pointer">
            <span :style="{'background-color':flowUrgentList[selectState].color}" class="color-box"></span>
            <span :style="{'color':flowUrgentList[selectState].color}">
              {{flowUrgentList[selectState].name}}</span>
          </div>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item v-for="(item,index) in flowUrgentList" :key="index" :command="item.state">
              <span :style="{'background-color':item.color}" class="color-box">
              </span>
              {{item.name}}
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <div class="flow-urgent-value" v-show="setting.opType!=='-1'">
          <span :style="{'background-color':flowUrgentList[selectState].color}" class="color-box"></span>
          <span :style="{'color':flowUrgentList[selectState].color}">{{flowUrgentList[selectState].name}}</span>
        </div>
      </template>
      <div v-if="!subFlowVisible" class="options">
        <el-dropdown v-if="moreBtnList.length" class="dropdown" placement="bottom" @command="handleMore">
          <el-button style="width:70px" :disabled="allBtnDisabled">
            更 多<i class="el-icon-arrow-down el-icon--right"></i>
          </el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item v-for="(item,index) in moreBtnList" :key="index" :command="item.key" class="dropdown-item">{{item.label}}</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
        <el-button v-if="setting.opType=='-1'" type="primary" @click="eventLauncher('submit')" :loading="candidateLoading" :disabled="allBtnDisabled">
          {{properties.submitBtnText||'提 交'}}</el-button>
        <el-button v-if="setting.opType == 1&&properties.hasAuditBtn" type="primary" @click="eventLauncher('audit')" :loading="candidateLoading">{{properties.auditBtnText||'通 过'}}
        </el-button>
        <el-button v-if="setting.opType == 0 && setting.status == 1&&(properties.hasPressBtn || properties.hasPressBtn===undefined)" type="primary" @click="press()">
          {{properties.pressBtnText||'催 办'}}</el-button>
        <el-button type="danger" v-if="setting.opType == 2 && properties.hasRevokeBtn" @click="actionLauncher('recall')">{{properties.revokeBtnText||'撤 回'}}</el-button>
        <el-button type="danger" v-if="setting.opType == 4 && setting.status==1 && !noOperateAuth" @click="actionLauncher('cancel')">
          终 止</el-button>
        <el-button v-if="!setting.hideCancelBtn && !isFromOaJump" @click="goBack()" :disabled="allBtnDisabled">
          {{$t('common.cancelButton')}}
        </el-button>
        <el-button v-if="isTopWindow && !IsInYecaiOA" @click="switchFullscreen(false)">全 屏</el-button>
      </div>
    </div>

    <div class="jnpf-common-form-wrapper">
      <div class="jnpf-common-form-wrapper__main">

        <el-tabs class="JNPF-el_tabs" v-model="activeTab">
          <el-tab-pane v-if="setting.opType!='4'&&!subFlowVisible" label="表单信息" v-loading="loading">
            <xjtIframe v-if="isIframeForm" ref="xjtIframe" :href="iframeUrl" :formOperates="flowDataObj.formOperates" height="100% !important" frameborder="0" />
            <component v-else :is="currentView" @close="goBack" ref="form" :config="setting" @eventReceiver="eventReceiver" @setLoad="setLoad" @setCandidateLoad="setCandidateLoad" @setPageLoad="setPageLoad" />
            <div v-if="(setting.opType==0||setting.opType==4) && activeTab==='0' &&!subFlowVisible" class="approve-result">
              <div class="approve-result-img" :class="flowTaskInfo.status | flowStatus()"></div>
            </div>
          </el-tab-pane>
          <el-tab-pane label="流程信息" v-loading="loading">
            <template v-if="!subFlowVisible">
              <Process :conf="flowTemplateJson" id="Process" v-if="flowTemplateJson.nodeId" :isEnd="flowTaskInfo.completion == 100" @subFlow='subFlow' :key="processKey" />
            </template>
            <template v-else>
              <el-tabs v-model="subFlowTab" @tab-click="activeClick" type="card">
                <el-tab-pane v-for="(item,index) in subFlowInfoList" :key="index" :label="item.flowTaskInfo.fullName" :name="item.flowTaskInfo.id">
                  <Process :conf="item.flowTemplateInfo.flowTemplateJson" :key="processKey" :isEnd="item.flowTaskInfo.completion == 100" />
                </el-tab-pane>
              </el-tabs>
            </template>
          </el-tab-pane>
          <el-tab-pane label="流转记录" v-if="setting.opType!='-1' || (setting.opType == '-1' && setting.status == 7)" v-loading="loading">
            <recordList :list='flowTaskOperatorRecordList' :endTime='endTime' :flowId="setting.flowId" :opType="setting.opType" @handelNodeLog='handelNodeLog' />
          </el-tab-pane>

          <!-- <el-tab-pane label="时间戳流转记录(Beta实验版)"
      v-if="setting.opType!='-1' || (setting.opType == '-1' && setting.status == 7)"
        v-loading="loading">
              <el-button size="mini" type="text" @click="DetailEx(setting.id)">
                时间戳流转记录(Beta实验版)</el-button>
      <DetailEx v-if="detailVisible" ref="DetailEx" @updateNodes='updateNodes'></DetailEx> -->
          <!-- </el-tab-pane> -->

          <el-tab-pane v-if="setting.opType!='-1' && isSummary" label="审批汇总" v-loading="loading" name="recordSummary">
            <RecordSummary :id='setting.id' :summaryType="summaryType" ref="recordSummary" />
          </el-tab-pane>
        </el-tabs>
      </div>
      <CommentExtra v-if="setting.opType != '-1' && isComment && !setting.hideCommentBtn" :taskId="setting.id" />
    </div>

    <el-dialog :title="eventType==='audit'?'审批通过':'审批退回'" :close-on-click-modal="false" :visible.sync="visible" class="JNPF-dialog JNPF-dialog_center" lock-scroll append-to-body :before-close="beforeClose" width='600px'>
      <el-form ref="candidateForm" :model="candidateForm" :label-width="candidateForm.candidateList.length||branchList.length?'130px':'80px'">
        <template v-if="eventType==='audit'">
          <el-form-item label="分支选择" prop="branchList" v-if="branchList.length" :rules="[{ required: true, message: `分支不能为空`, trigger: 'change' }]">
            <el-select v-model="candidateForm.branchList" multiple placeholder="请选择审批分支" clearable @change="onBranchChange">
              <el-option v-for="item in branchList" :key="item.nodeId" :label="item.nodeName" :value="item.nodeId" />
            </el-select>
          </el-form-item>
          <el-form-item :label="item.nodeName+item.label" :prop="'candidateList.' + i + '.value'" v-for="(item,i) in candidateForm.candidateList" :key="i" :rules="item.rules">
            <candidate-user-select v-model="item.value" multiple :placeholder="'请选择'+item.label" :taskId="setting.taskId" :formData="formData" :nodeId="item.nodeId" v-if="item.hasCandidates" />
            <JnpfUserSelect v-model="item.value" multiple :placeholder="'请选择'+item.label" title="候选人员" v-else />
          </el-form-item>
        </template>
        <template v-if="properties.rejectType &&eventType!=='audit'&&showReject">
          <el-form-item label="退回节点" prop="rejectStep">
            <el-select v-model="candidateForm.rejectStep" placeholder="请选择退回节点" :disabled='properties.rejectStep!=="2"'>
              <el-option v-for="item in rejectList" :key="item.nodeCode" :label="item.nodeName" :value="item.nodeCode">
              </el-option>
            </el-select>
          </el-form-item>
          <template v-if="properties.rejectType==3">
            <el-form-item prop="rejectRadio">
              <el-radio-group v-model="candidateForm.rejectType" class="form-item-content">
                <el-radio :label=1>重新审批
                  <el-tooltip content="若流程为A->B->C,C退回至A，则C->A->B->C" placement="top">
                    <i class="el-icon-question tooltip-question"></i>
                  </el-tooltip>
                </el-radio>
                <el-radio :label=2>直接提交给我
                  <el-tooltip content="若流程为A->B->C,C退回至A，则C->A->C" placement="top">
                    <i class="el-icon-question tooltip-question"></i>
                  </el-tooltip>
                </el-radio>
              </el-radio-group>
            </el-form-item>
          </template>
        </template>
        <template v-if="properties.hasOpinion">
          <el-form-item label="审批意见" prop="handleOpinion">
            <el-input v-model="candidateForm.handleOpinion" placeholder="请输入审批意见" type="textarea" :rows="4" />
            <CommonWordsDialog ref="commonWordsDialog" @change="common" />
          </el-form-item>
          <el-form-item label="审批附件" prop="fileList">
            <JnpfUploadFile v-model="candidateForm.fileList" :limit="3" />
          </el-form-item>
        </template>
        <el-form-item label="手写签名" prop="signImg" v-if="properties.hasSign" :rules="[{ required: true, message: `请签名`, trigger: 'change' }]">
          <jnpf-sign v-model="candidateForm.signImg" :isInvoke="true" />
        </el-form-item>
        <el-form-item label="抄送人员" v-if="properties.isCustomCopy">
          <JnpfUserSelect v-model="copyIds" placeholder="请选择" multiple />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="visible = false">{{$t('common.cancelButton')}}</el-button>
        <el-button type="primary" @click="handleApproval()" :loading="approvalBtnLoading">
          {{$t('common.confirmButton')}}
        </el-button>
      </span>

    </el-dialog>
    <!-- 流程节点变更复活对话框 -->
    <el-dialog :title="flowTaskInfo.completion==100?'复活':'变更'" :close-on-click-modal="false" :visible.sync="resurgenceVisible" class="JNPF-dialog JNPF-dialog_center" lock-scroll append-to-body width='600px'>
      <el-form label-width="80px" :model="resurgenceForm" :rules="resurgenceRules" ref="resurgenceForm">
        <el-form-item :label="flowTaskInfo.completion==100?'复活节点':'变更节点'" prop="taskNodeId">
          <el-select v-model="resurgenceForm.taskNodeId" :placeholder="flowTaskInfo.completion==100?'请选择复活节点':'请选择变更节点'">
            <el-option v-for="item in resurgenceNodeList" :key="item.id" :label="item.nodeName" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item :label="flowTaskInfo.completion==100?'复活意见':'变更意见'" prop="handleOpinion">
          <el-row>
            <el-col :span="24">
              <el-input type="textarea" v-model="resurgenceForm.handleOpinion" placeholder="请填写意见" :rows="4" />
            </el-col>
          </el-row>
        </el-form-item>
        <el-form-item :label="flowTaskInfo.completion==100?'复活附件':'变更附件'" prop="fileList">
          <JnpfUploadFile v-model="resurgenceForm.fileList" :limit="3" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="resurgenceVisible = false">{{$t('common.cancelButton')}}</el-button>
        <el-button type="primary" @click="handleResurgence()" :loading="resurgenceBtnLoading">
          {{$t('common.confirmButton')}}
        </el-button>
      </span>
    </el-dialog>
    <print-browse :visible.sync="printBrowseVisible" :id="printTemplateId" :formId="setting.id" :fullName="setting.fullName" />
    <candidate-form :visible.sync="candidateVisible" :candidateList="candidateList" :branchList="branchList" :taskId="setting.taskId" :formData="formData" ref="candidateForm" @submitCandidate="submitCandidate" :isCustomCopy="properties.isCustomCopy" />
    <error-form :visible.sync="errorVisible" :nodeList="errorNodeList" @submit="handleError" />
    <actionDialog v-if="actionVisible" ref="actionDialog" :assignNodeList="assignNodeList" :nodeModelList="nodeModelList" @submit="actionReceiver" />
    <SuspendDialog v-if="suspendVisible" ref="suspendDialog" @submit="suspendReceiver" />
    <HasFreeApprover :visible.sync="hasFreeApproverVisible" :taskId="setting.taskId" :formData="formData" :properties="properties" @close="approverDialog" />
    <FlowBox v-if="flowBoxVisible" ref="FlowBox" @close="flowBoxVisible = false" />
    <PrintDialog v-if="printDialogVisible" ref="printDialog" @change="printBrowseHandle">
    </PrintDialog>
    <EventLog v-if="logVisible" ref="EventLog" @close="logVisible = false" />
  </div>
  <!-- </transition> -->
</template>

<script>
  import { mapGetters } from 'vuex'
  import PrintDialog from '@/components/PrintDialog'
  import EventLog from './EventLog'
  import DetailEx from './DetailEx'
  import { FlowBeforeInfo, Audit, Reject, Transfer, Invoke, Cc, MultiAdd, TaskCancel, CounterSignAbstention, LockOrUnLock, Assist, Recall, Cancel, Assign, SaveAudit, Candidates, CandidateUser, Resurgence, ResurgenceList, RejectList, suspend, restore, subFlowInfo, ShareEx, CcBatch, SpecialJump, ApprovalCancel, getFlowInfoByProcessInstanceId } from '@/api/workFlow/FlowBefore'
  import { Revoke, Press } from '@/api/workFlow/FlowLaunch'
  import { Create, Update } from '@/api/workFlow/workFlowForm'
  import recordList from './RecordList'
  import CommentExtra from '@/views/workFlow/CommentExtra/index.vue'
  import RecordSummary from './RecordSummary'
  import CandidateForm from './CandidateForm'
  import ErrorForm from './ErrorForm'
  import CandidateUserSelect from './CandidateUserSelect'
  import Process from '@/components/Process/Preview'
  import PrintBrowse from '@/components/PrintBrowse'
  import ActionDialog from '@/views/workFlow/components/ActionDialog'
  import HasFreeApprover from './HasFreeApprover'
  import SuspendDialog from './SuspendDialog'
  import CommonWordsDialog from './CommonWordsDialog';
  import xjtIframe from '@/components/xjtIframe';
  import { getIframeUrl } from '@/utils/flow';
  import { getIsInYecaiOA } from "@/utils/auth";
  import { printDom } from "@/utils/index";

  // 收集节点的userName，在流程图上hover展示
  const reflectUsername = (list) => {
    const _userNames = list?.length
      ?
      list.reduce((pre, cur) => {
        const { nodeCode, userName } = cur;
        if (nodeCode && !pre[nodeCode]) {
          pre[nodeCode] = userName
        } else if (pre[nodeCode]) {
          pre[nodeCode] += `、\n${userName}`
        }
        return pre
      }, {})
      :
      {};
    return _userNames
  }

  export default {
    name: 'FlowBox',
    components: { PrintDialog, HasFreeApprover, recordList, Process, PrintBrowse, CommentExtra, RecordSummary, CandidateForm, CandidateUserSelect, ErrorForm, ActionDialog, SuspendDialog, CommonWordsDialog, EventLog, DetailEx, xjtIframe },

    props: {
      isDone: {
        type: String,
        default: '',
      },
    },

    data() {
      return {
        detailVisible: false,
        activeItem: {},
        printTemplateId: '',
        printDialogVisible: false,
        subFlowTab: '',
        resurgenceVisible: false,
        actionVisible: false,
        resurgenceForm: {
          taskNodeId: '',
          handleOpinion: '',
          fileList: []
        },
        resurgenceRules: {
          taskNodeId: [
            {
              required: true,
              message: '请选择节点',
              trigger: 'change'
            }
          ],
        },
        logVisible: false,
        previewVisible: false,
        assignNodeList: [],
        resurgenceNodeList: [],
        nodeModelList: [],
        currentView: '',
        previewTitle: '',
        formData: {},
        setting: {},
        monitorList: [{ fullName: '1', flowName: '1', startTime: '1', userName: '1', thisStep: '1' }, { fullName: '1', flowName: '1', startTime: '1', userName: '1', thisStep: '1' }],
        flowFormInfo: {},
        flowTemplateInfo: {},
        flowTaskInfo: {},
        flowTaskNodeList: [],
        flowTemplateJson: {},
        flowTaskOperatorRecordList: [],
        properties: {},
        endTime: 0,
        suspendVisible: false,
        visible: false,
        handleId: '',
        activeTab: '0',
        isComment: false,
        isSummary: false,
        summaryType: 0,
        loading: false,
        btnLoading: false,
        approvalBtnLoading: false,
        resurgenceBtnLoading: false,
        candidateLoading: false,
        candidateVisible: false,
        hasFreeApproverVisible: false,
        candidateType: 1,
        countersignOver: false,
        branchList: [],
        candidateList: [],
        candidateForm: {
          branchList: [],
          candidateList: [],
          fileList: [],
          handleOpinion: '',
          rejectStep: '',
          rejectType: 1,
          signImg: ''
        },
        printBrowseVisible: false,
        rejectList: [],
        showReject: false,
        eventType: '',
        copyIds: [],
        fullName: '',
        thisStep: '',
        allBtnDisabled: false,
        flowUrgent: 1,
        flowUrgentList: [
          { name: '普通', color: '#409EFF', state: 1, },
          { name: '重要', color: '#E6A23C', state: 2, },
          { name: '紧急', color: '#F56C6C', state: 3, },
        ],
        errorVisible: false,
        errorNodeList: [],
        isValidate: false,
        moreBtnList: [],
        subFlowVisible: false,
        flowBoxVisible: false,
        subFlowInfoList: [],
        commonWordsVisible: false,
        noOperateAuth: true, // 是否没有操作权限
        processKey: 0,
        isIframeForm: false, // 是否是通过iframe嵌入的外部表单页面
        iframeUrl: '',
        flowDataObj: {
          formData: {},
          formOperates: [],
        },
        isTopWindow: false,
        IsInYecaiOA: false,
        isFullScreen: false,
        isFromOaJump: false, // 是否为OA跳转进来的
      }
    },

    computed: {
      ...mapGetters(['userInfo']),

      title() {
        if ([2, 3, 4].includes(this.setting.opType)) return this.fullName
        return this.thisStep ? this.fullName + '/' + this.thisStep : this.fullName
      },
      selectState() {
        const index = this.flowUrgentList.findIndex(c => this.flowUrgent === c.state)
        return index
      },
    },

    watch: {
      activeTab(val) {
        if (val === 'recordSummary') {
          this.$refs.recordSummary && this.$refs.recordSummary.init()
        }
      },
    },

    created() {
      this.isTopWindow = window === window.top;
      this.IsInYecaiOA = getIsInYecaiOA();
    },

    beforeDestroy() {
      this.switchFullscreen(true);
    },

    methods: {
      DetailEx(id) {
        this.detailVisible = true
        this.$nextTick(() => {
          this.$refs.DetailEx.openDialog(id)
        })
      },
      updateNodes() {
        this.$emit('updateNodes', this.setting.id);
        this.goBack()
      },
      common(val) {
        this.commonWordsVisible = false
        if (val) {
          if (this.resurgenceVisible) {
            this.resurgenceForm.handleOpinion += val.commonWordsText
          } else {
            this.candidateForm.handleOpinion += val.commonWordsText
          }

        }
      },
      beforeClose() {
        this.visible = false
        this.$refs.commonWordsDialog.close()
      },
      addSign() {
        this.signVisible = true
        this.$nextTick(() => {
          this.$refs.SignImg.init()
        })
      },
      signDialog(val) {
        this.signVisible = false
        if (val) {
          this.signImg = val
        }
      },
      approverDialog(needClose) {
        if (needClose) this.$emit('close', true)
      },
      handelNodeLog(item) {
        this.logVisible = true
        this.$nextTick(() => {
          this.$refs.EventLog.init(item.taskNodeId, item.nodeName)
        })
      },
      activeClick() {
        let data = this.subFlowInfoList.filter(o => o.flowTaskInfo.id == this.subFlowTab) || []
        if (data.length) {
          this.fullName = data[0].flowTaskInfo.fullName
          this.flowTaskOperatorRecordList = data[0].flowTaskOperatorRecordList || []
          let templateJson = data[0].flowTemplateInfo.flowTemplateJson && typeof data[0].flowTemplateInfo.flowTemplateJson === "string" ? JSON.parse(data[0].flowTemplateInfo.flowTemplateJson || null) : data[0].flowTemplateInfo.flowTemplateJson
          data[0].flowTemplateInfo.flowTemplateJson = templateJson
          this.isComment = templateJson.properties.isComment
          this.isSummary = templateJson.properties.isSummary
          this.summaryType = templateJson.properties.summaryType
          this.flowUrgent = data[0].flowTaskInfo.flowUrgent || 1
          this.setting.id = data[0].flowTaskInfo.id

          if (data[0].flowTaskNodeList.length) {
            let assignNodeList = []
            for (let i = 0; i < data[0].flowTaskNodeList.length; i++) {
              const nodeItem = data[0].flowTaskNodeList[i]
              if (data.opType == 4 || data.opType == 1 && nodeItem.type == 1 && nodeItem.nodeType === 'approver') {
                assignNodeList.push(nodeItem)
              }
              const loop = data => {
                if (Array.isArray(data)) data.forEach(d => loop(d))
                if (data.nodeId === nodeItem.nodeCode) {
                  if (nodeItem.type == 0) data.state = 'state-past'
                  // if (nodeItem.type == 1) data.state = 'state-curr'
                  if (nodeItem.type == 1) {
                    data.state = 'state-curr';
                    data.tooltip = reflectUsername(this.flowTaskOperatorRecordList)[nodeItem.nodeCode]
                  }
                  if (nodeItem.nodeType === 'approver' || nodeItem.nodeType === 'start' || nodeItem.nodeType === 'subFlow') data.content = nodeItem.userName
                  return
                }
                if (data.conditionNodes && Array.isArray(data.conditionNodes)) loop(data.conditionNodes)
                if (data.childNode) loop(data.childNode)
              }
              loop(data[0].flowTemplateInfo.flowTemplateJson)
            }
            this.assignNodeList = assignNodeList
          } else {
            data[0].flowTemplateInfo.flowTemplateJson.state = 'state-curr'
          }
          this.processKey = +new Date()
        }
      },
      subFlow(enCode) {
        let flowTaskNodeList = this.flowTaskNodeList.filter(res => res.nodeCode == enCode)
        if (!flowTaskNodeList.length) return
        if (!flowTaskNodeList[0].type || flowTaskNodeList[0].nodeType != 'subFlow') return
        let item = {
          subFlowVisible: true,
          ...flowTaskNodeList,
          ...this.setting,
        }
        if (document.getElementById('Process')) document.getElementById('Process').style.display = 'none'
        this.flowBoxVisible = true
        this.$nextTick(() => {
          this.$refs.FlowBox.init(item)
        })
      },
      handleResurgence(errorRuleUserList) {
        this.$refs['resurgenceForm'].validate((valid) => {
          if (!valid) return
          let query = {
            ...this.resurgenceForm,
            taskId: this.setting.taskId,
            resurgence: this.flowTaskInfo.completion == 100
          }
          if (errorRuleUserList) query.errorRuleUserList = errorRuleUserList
          this.resurgenceBtnLoading = true
          Resurgence(query).then(res => {
            const errorData = res.data
            if (errorData && Array.isArray(errorData) && errorData.length) {
              this.errorNodeList = errorData
              this.eventType = 'resurgence'
              this.errorVisible = true
              this.resurgenceBtnLoading = false
            } else {
              this.$message({
                type: 'success',
                message: res.msg,
                duration: 1000,
                onClose: () => {
                  this.resurgenceBtnLoading = false
                  this.visible = false
                  this.errorVisible = false
                  this.$emit('close', true)
                }
              })
            }
          }).catch(() => { this.resurgenceBtnLoading = false })
        })
      },
      flowResurgence() {
        this.resurgenceVisible = true
        ResurgenceList(this.setting.taskId).then(res => {
          this.resurgenceNodeList = res.data
        })
      },
      goBack(isRefresh) {
        if (this.isFromOaJump) {
          // 避免回到列表页
          window.parent.postMessage({
            closed: true
          }, '\*');
        } else {
          if (this.subFlowVisible) document.getElementById('Process').style.display = 'block'
          this.$emit('close', isRefresh)
        }
      },

      switchFullscreen(isExitFullScreen) {
        this.isFullScreen = isExitFullScreen ? false : !this.isFullScreen;
        const appMain = document.querySelector('.app-main');
        const sidebar = document.querySelector('.sidebar-container');
        if (appMain) {
          this.isFullScreen ? appMain.classList.add('full-screen') : appMain.classList.remove('full-screen');
        }
        if (sidebar) {
          sidebar.style.zIndex = this.isFullScreen ? 1 : 1001;
        }
      },

      init(data) {
        this.isFromOaJump = data.isFromOaJump;
        this.isComment = false
        this.activeTab = '0'
        this.setting = data
        if (data.subFlowVisible) {
          this.subFlowInfo(data)
        } else {
          /**
           * opType
           * -1 - 我发起的新建/编辑
           * 0 - 我发起的详情
           * 1 - 待办事宜
           * 2 - 已办事宜
           * 3 - 抄送事宜
           * 4 - 流程监控
           */
          this.getBeforeInfo(data);
        }
      },

      getBeforeInfo(data) {
        this.loading = true;
        const getFlowInfoFun = data.processInstanceId ? getFlowInfoByProcessInstanceId : FlowBeforeInfo;
        const id = data.processInstanceId ? data.processInstanceId : (data.id || 0);
        const params = data.processInstanceId ? {} : { taskNodeId: data.taskNodeId, taskOperatorId: data.taskId, flowId: data.flowId };
        getFlowInfoFun(id, params).then(res => {
          this.flowDataObj = res.data || {};
          this.flowFormInfo = res.data.flowFormInfo
          this.flowTaskInfo = res.data.flowTaskInfo || {}
          this.flowTemplateInfo = res.data.flowTemplateInfo
          this.noOperateAuth = res.data.noOperateAuth || false;
          const fullName = data.opType == '-1' ? this.flowTemplateInfo.fullName : this.flowTaskInfo.fullName
          data.fullName = fullName
          this.fullName = fullName
          this.thisStep = this.flowTaskInfo.thisStep
          this.flowUrgent = this.flowTaskInfo.flowUrgent || 1
          data.status = this.flowTaskInfo.status;
          data.type = this.flowTemplateInfo.type
          data.draftData = res.data.draftData || null
          data.formData = res.data.formData || {}
          this.nodeModelList = res.data.nodeModelList || {}
          const { formType, enCode, urlAddress } = this.flowFormInfo;
          data.formEnCode = enCode;
          // console.log('formType --- ' + formType)
          // const formUrl = formType == 2 ? 'workFlow/workFlowForm/dynamicForm' : urlAddress ? urlAddress.replace(/\s*/g, '') : `workFlow/workFlowForm/${enCode}`;
          // this.currentView = (resolve) => require([`@/views/${formUrl}`], resolve);
          this.isIframeForm = false;
          // formType: 1-功能表单 或 需要通过iframe嵌入的表单页面, 2-自定义拖拽的表单
          if (formType === 1) {
            this.iframeUrl = getIframeUrl(data.formData, urlAddress, this.isDone);
            if (this.iframeUrl) {
              this.isIframeForm = true;
            } else {
              this.$message.error('暂无匹配的业务流程表单');
            }
          } else {
            const formUrl = 'workFlow/workFlowForm/dynamicForm';
            this.currentView = (resolve) => require([`@/views/${formUrl}`], resolve);
          }

          this.flowTaskNodeList = res.data.flowTaskNodeList || []
          this.flowTemplateJson = this.flowTemplateInfo.flowTemplateJson ? JSON.parse(this.flowTemplateInfo.flowTemplateJson) : null
          this.isComment = this.flowTemplateJson.properties.isComment
          this.isSummary = this.flowTemplateJson.properties.isSummary
          this.summaryType = this.flowTemplateJson.properties.summaryType
          this.flowTaskOperatorRecordList = res.data.flowTaskOperatorRecordList || []
          this.flowTaskOperatorRecordList = this.flowTaskOperatorRecordList.reverse()
          this.properties = res.data.approversProperties || {}
          this.candidateForm.rejectType = this.properties.rejectType == 3 ? 1 : this.properties.rejectType
          this.endTime = this.flowTaskInfo.completion == 100 ? this.flowTaskInfo.endTime : 0
          data.formConf = this.flowFormInfo.propertyJson
          if (data.opType != 1 && data.opType != '-1') data.readonly = true
          data.formOperates = res.data.formOperates || []
          if (data.opType == 0) {
            for (let i = 0; i < data.formOperates.length; i++) {
              data.formOperates[i].write = false
            }
          }

          data.flowTemplateJson = this.flowTemplateJson
          if (this.flowTaskNodeList.length) {
            let assignNodeList = []
            for (let i = 0; i < this.flowTaskNodeList.length; i++) {
              const nodeItem = this.flowTaskNodeList[i]
              if ((data.opType == 1 || data.opType == 4) && nodeItem.type == 1 && nodeItem.nodeType === 'approver') {
                assignNodeList.push(nodeItem)
              }
              const loop = data => {
                if (Array.isArray(data)) data.forEach(d => loop(d))
                if (data.nodeId === nodeItem.nodeCode) {
                  if (nodeItem.type == 0) data.state = 'state-past'
                  // if (nodeItem.type == 1) data.state = 'state-curr'
                  if (nodeItem.type == 1) {
                    data.state = 'state-curr';
                    data.tooltip = reflectUsername(this.flowTaskOperatorRecordList)[nodeItem.nodeCode]
                  }
                  if (nodeItem.nodeType === 'approver' || nodeItem.nodeType === 'start' || nodeItem.nodeType === 'subFlow') data.content = nodeItem.userName
                  return
                }
                if (data.conditionNodes && Array.isArray(data.conditionNodes)) loop(data.conditionNodes)
                if (data.childNode) loop(data.childNode)
              }
              loop(this.flowTemplateJson)
            }
            this.assignNodeList = assignNodeList
          } else {
            this.flowTemplateJson.state = 'state-curr'
          }
          this.processKey = +new Date()
          this.setting = data
          this.initBtnList()
        }).finally(() => { this.loading = false })
      },

      initBtnList() {
        const list = []
        const setting = this.setting
        const opType = this.setting.opType
        const properties = this.properties
        const flowTaskInfo = this.flowTaskInfo
        // console.log('当前opType' + opType)
        // console.log('Status为:' + setting.status)
        if (opType == '-1' && !setting.hideCancelBtn) {
          list.push({ label: properties.saveBtnText || '暂 存', key: 'save' })
        }
        if (opType == 0 && setting.status == 1 && (properties.hasRevokeBtn || properties.hasRevokeBtn === undefined)) {
          list.push({ label: properties.revokeBtnText || '撤 回', key: 'revoke' })
          list.push({ label: properties.shareBtnText || '关注-取关', key: 'shareEx' })
        }
        if (opType != 4 && setting.id && properties.hasPrintBtn && properties.printId) list.push({ label: properties.printBtnText || '打 印', key: 'print' })
        if (opType == 1) {
          if (properties.hasTransferBtn) list.push({ label: properties.transferBtnText || '转 审', key: 'transfer' })
          if (properties.hasSaveBtn) list.push({ label: properties.saveBtnText || '暂 存', key: 'saveAudit' })
          if (properties.hasRejectBtn) list.push({ label: properties.rejectBtnText || '退 回', key: 'reject' })
          if (properties.hasFreeApproverBtn) list.push({ label: properties.hasFreeApproverBtnText || '加 签', key: 'hasFreeApprover' })
          if (properties.hasCancelBtn) list.push({ label: properties.cancelBtnText || '不同意', key: 'approvalCancel' });
          if (properties.hasAbstentionBtn) list.push({ label: properties.abstentionBtnText || '会签弃权', key: 'counterSignAbstention' });
          if (properties.hasLockOrUnLockBtn) list.push({ label: properties.LockOrUnLockBtnText || '锁定/解锁', key: 'lockOrUnLock' });
          if (properties.hasInvokeBtn) list.push({ label: properties.invokeBtnText || '委 派', key: 'invoke' })
          if (properties.hasCopyBtn) list.push({ label: properties.copyBtnText || '抄 送', key: 'cc' })
          if (properties.hasMultiAddBtn) list.push({ label: properties.multiAddBtnText || '普 通 加 签', key: 'multiAdd' })
          if (properties.hasTerminationBtn) list.push({ label: properties.terminationBtnText || '终 止', key: 'taskCancel' })
          if (properties.hasAssistBtn) list.push({ label: properties.assistBtnText || '协 办', key: 'assist' })
          if (properties.hasJumpBtn) list.push({ label: properties.jumpBtnText || '特 送', key: 'specialJump' })
          list.push({ label: properties.shareBtnText || '关注-取关', key: 'shareEx' })
        }
        if (opType == 3) {
          list.push({ label: properties.shareBtnText || '关注-取关', key: 'shareEx' })
          list.push({ label: properties.copyBtnText || '抄 送', key: 'ccBatch' })
        }
        if (opType == 4) {
          if (this.noOperateAuth) return (this.moreBtnList = []);
          if (flowTaskInfo.completion == 100) list.push({ label: '复 活', key: 'resurgence' })
          if (flowTaskInfo.completion > 0 && flowTaskInfo.completion < 100 && !flowTaskInfo.rejectDataId && (setting.status == 1 || setting.status == 3)) list.push({ label: '变 更', key: 'resurgence' })
          if (setting.status == 1) list.push({ label: '指 派', key: 'assign' })
          if (flowTaskInfo.status == 1) list.push({ label: '挂 起', key: 'suspend' })
          if (flowTaskInfo.status == 6) list.push({ label: '恢 复', key: 'recovery' })
        }
        list.push({ label: '打印预览', key: 'printByBrowse' });
        this.moreBtnList = list
      },
      subFlowInfo(data) {
        this.loading = true;
        this.activeTab = '0'
        this.subFlowVisible = true
        subFlowInfo(data[0].id, data[0].id).then(res => {
          this.subFlowInfoList = res.data || []
          this.subFlowTab = this.subFlowInfoList[0].flowTaskInfo.id
          this.flowUrgent = this.subFlowInfoList[0].flowTaskInfo.flowUrgent || 1
          this.fullName = this.subFlowInfoList[0].flowTaskInfo.fullName
          this.flowTaskOperatorRecordList = this.subFlowInfoList[0].flowTaskOperatorRecordList || []
          this.flowTaskOperatorRecordList = this.flowTaskOperatorRecordList.reverse()

          for (let index = 0; index < this.subFlowInfoList.length; index++) {
            let element = this.subFlowInfoList[index];
            element.flowTemplateInfo.flowTemplateJson = element.flowTemplateInfo && element.flowTemplateInfo.flowTemplateJson ? JSON.parse(element.flowTemplateInfo.flowTemplateJson) : {}
            if (element.flowTaskNodeList.length) {
              let assignNodeList = []
              for (let i = 0; i < element.flowTaskNodeList.length; i++) {
                const nodeItem = element.flowTaskNodeList[i]
                data.opType == 4 && nodeItem.type == 1 && nodeItem.nodeType === 'approver' && assignNodeList.push(nodeItem)
                const loop = data => {
                  if (Array.isArray(data)) data.forEach(d => loop(d))
                  if (data.nodeId === nodeItem.nodeCode) {
                    if (nodeItem.type == 0) data.state = 'state-past'
                    // if (nodeItem.type == 1) data.state = 'state-curr'
                    if (nodeItem.type == 1) {
                      data.state = 'state-curr';
                      data.tooltip = reflectUsername(this.flowTaskOperatorRecordList)[nodeItem.nodeCode]
                    }
                    if (nodeItem.nodeType === 'approver' || nodeItem.nodeType === 'start' || nodeItem.nodeType === 'subFlow') data.content = nodeItem.userName
                    return
                  }
                  if (data.conditionNodes && Array.isArray(data.conditionNodes)) loop(data.conditionNodes)
                  if (data.childNode) loop(data.childNode)
                }
                loop(element.flowTemplateInfo.flowTemplateJson)
              }
              element.assignNodeList = assignNodeList
            } else {
              element.flowTemplateInfo.flowTemplateJson.state = 'state-curr'
            }
            let templateJson = element.flowTemplateInfo.flowTemplateJson
            this.isComment = templateJson.properties.isComment
            this.isSummary = templateJson.properties.isSummary
            this.summaryType = templateJson.properties.summaryType
            this.setting.id = this.subFlowInfoList[0].flowTaskInfo.id
          }
        }).finally(() => { this.loading = false })


      },
      printBrowseHandle(id) {
        this.printTemplateId = id
        this.printDialogVisible = false
        this.printBrowseVisible = true
      },
      printDialog() {
        this.printDialogVisible = true
        this.$nextTick(() => {
          this.$refs.printDialog.init(this.properties.printId)
        })
      },
      handleMore(e) {
        if (e == 'revoke') return this.actionLauncher('revoke')
        if (e == 'transfer') return this.actionLauncher('transfer')
        if (e == 'invoke') return this.actionLauncher('invoke')
        if (e == 'taskCancel') return this.actionLauncher('taskCancel')
        if (e == 'multiAdd') return this.actionLauncher('multiAdd')
        if (e == 'specialJump') return this.actionLauncher('specialJump')
        if (e == 'shareEx') return this.actionLauncher('shareEx')
        if (e == 'assist') return this.actionLauncher('assist')
        if (e == 'cc') return this.actionLauncher('cc')
        if (e == 'ccBatch') return this.actionLauncher('ccBatch')
        if (e == 'saveAudit') return this.eventLauncher('saveAudit')
        if (e == 'reject') return this.eventReceiver({}, 'reject')
        if (e == 'resurgence') return this.flowResurgence()
        if (e == 'assign') return this.actionLauncher('assign')
        if (e == 'approvalCancel') return this.actionLauncher('approvalCancel');
        if (e == 'counterSignAbstention') return this.actionLauncher('counterSignAbstention');
        if (e == 'lockOrUnLock') return this.actionLauncher('lockOrUnLock');
        if (e == 'print') return this.printDialog()
        if (e == 'printByBrowse') return this.printByBrowse()
        if (e == 'suspend') return this.suspend()
        if (e == 'recovery') return this.recovery()
        this.eventLauncher(e)
      },

      printByBrowse() {
        if (this.isIframeForm) {
          const ycIframe = this.$refs.xjtIframe?.$refs.currentIframeRef;
          ycIframe && ycIframe.contentWindow?.focus();
          ycIframe && ycIframe.contentWindow?.print();
        } else {
          printDom(this.$refs.form.$el, this.title);
        }
      },

      suspend() {
        this.suspendVisible = true
        this.$nextTick(() => {
          this.$refs.suspendDialog.init(this.setting.id)
        })
      },
      recovery() {
        let data = {
          handleOpinion: '',
          fileList: [],
        }
        restore(this.setting.id, data).then(res => {
          this.$message({
            message: res.msg,
            type: 'success',
            duration: 1500,
            onClose: () => {
              this.$emit('close', true)
            }
          })
        }).catch(() => {
          this.$refs.suspendDialog.btnLoading = false
        })
      },
      suspendReceiver(dataForm) {
        suspend(this.setting.id, dataForm).then(res => {
          this.$message({
            message: res.msg,
            type: 'success',
            duration: 1500,
            onClose: () => {
              this.$emit('close', true)
            }
          })
        })
      },
      eventLauncher(eventType) {
        if (this.isIframeForm) {
          this.eventReceiver({}, eventType);
        } else {
          this.$refs.form && this.$refs.form.dataFormSubmit(eventType, this.flowUrgent);
        }
      },
      eventReceiver(formData, eventType) {
        this.formData = formData
        if (this.isIframeForm) {
          this.formData = {
            ...formData,
            ...this.flowDataObj.formData,
            formData: this.flowDataObj.formData,
          }
        }
        this.formData.flowId = this.setting.flowId
        this.formData.id = this.setting.id
        this.eventType = eventType
        if (eventType === 'save' || eventType === 'submit') {
          return this.submitOrSave()
        }
        if (eventType === 'saveAudit') {
          return this.saveAudit()
        }
        if (eventType === 'hasFreeApprover') {
          return this.hasFreeApproverVisible = true
        }
        if (eventType === 'audit' || eventType === 'reject') {
          this.handleId = ''
          this.candidateForm.handleOpinion = ''
          this.candidateForm.signImg = ''
          this.candidateForm.fileList = []
          this.copyIds = []
          this.isValidate = false
          if (this.properties.hasSign) this.candidateForm.signImg = this.userInfo.signImg
          if (eventType === 'reject') {
            RejectList(this.setting.taskId).then(res => {
              this.showReject = res.data.isLastAppro
              this.rejectList = res.data.list || []
              this.candidateForm.rejectStep = this.rejectList.length && this.rejectList[0].nodeCode || ''
              if (!this.properties.hasSign && !this.properties.hasOpinion && !this.properties.isCustomCopy && !this.showReject) {
                this.$confirm('此操作将退回该审批单，是否继续？', '提示', {
                  type: 'warning'
                }).then(() => {
                  this.handleApproval()
                }).catch(() => { });
                return
              }
              this.isValidate = true
              this.visible = true
            }).catch({})
            return
          }
          this.candidateLoading = true
          Candidates(this.setting.taskId, this.formData).then(res => {
            let data = res.data
            this.candidateType = data.type
            this.countersignOver = data.countersignOver
            this.candidateLoading = false
            this.candidateForm.branchList = []
            this.branchList = []
            if (data.type == 1) {
              this.branchList = res.data.list.filter(o => o.isBranchFlow)
              let list = res.data.list.filter(o => !o.isBranchFlow && o.isCandidates)
              this.candidateForm.candidateList = list.map(o => ({
                ...o,
                isDefault: true,
                label: '审批人',
                value: [],
                rules: [{ required: true, message: `审批人不能为空`, trigger: 'click' }]
              }))
              this.$nextTick(() => {
                this.$refs['candidateForm'].resetFields()
              })
              this.isValidate = true
              this.visible = true
            } else if (data.type == 2) {
              let list = res.data.list.filter(o => o.isCandidates)
              this.candidateForm.candidateList = list.map(o => ({
                ...o,
                label: '审批人',
                value: [],
                rules: [{ required: true, message: `审批人不能为空`, trigger: 'click' }]
              }))
              this.$nextTick(() => {
                this.$refs['candidateForm'].resetFields()
              })
              this.isValidate = true
              this.visible = true
            } else {
              this.candidateForm.candidateList = []
              if (!this.properties.hasSign && !this.properties.hasOpinion && !this.properties.hasFreeApprover && !this.properties.isCustomCopy) {
                this.$confirm('此操作将通过该审批单，是否继续？', '提示', {
                  type: 'warning'
                }).then(() => {
                  this.handleApproval()
                }).catch(() => { });
                return
              }
              this.isValidate = true
              this.visible = true
            }
          }).catch(() => {
            this.candidateLoading = false
          })
        }
      },
      onBranchChange(val) {
        const defaultList = this.candidateForm.candidateList.filter(o => o.isDefault)
        if (!val.length) return this.candidateForm.candidateList = defaultList
        let list = []
        for (let i = 0; i < val.length; i++) {
          inner: for (let j = 0; j < this.branchList.length; j++) {
            let o = this.branchList[j]
            if (val[i] === o.nodeId && o.isCandidates) {
              list.push({
                ...o,
                label: '审批人',
                value: [],
                rules: [{ required: true, message: `审批人不能为空`, trigger: 'click' }]
              })
              break inner
            }
          }
        }
        this.candidateForm.candidateList = [...defaultList, ...list]
      },
      saveAudit() {
        this.btnLoading = true
        SaveAudit(this.setting.taskId, this.formData).then(res => {
          this.$message({
            message: res.msg,
            type: 'success',
            duration: 1500,
            onClose: () => {
              this.btnLoading = false
              this.$emit('close', true)
            }
          })
        }).catch(() => {
          this.btnLoading = false
        })
      },
      submitOrSave() {
        this.formData.status = this.eventType === 'submit' ? 0 : 1
        this.formData.flowUrgent = this.flowUrgent
        if (this.setting.delegateUserList) {//受委托人不为空的时候走委托创建流程
          this.formData.delegateUserList = this.setting.delegateUserList
        }

        if (this.eventType === 'save') return this.handleRequest()
        this.candidateLoading = true
        Candidates(0, this.formData).then(res => {
          let data = res.data
          this.candidateLoading = false
          this.candidateType = data.type
          this.countersignOver = data.countersignOver
          if (data.type == 1) {
            this.branchList = res.data.list.filter(o => o.isBranchFlow)
            this.candidateList = res.data.list.filter(o => !o.isBranchFlow && o.isCandidates)
            this.candidateVisible = true
          } else if (data.type == 2) {
            this.branchList = []
            this.candidateList = res.data.list.filter(o => o.isCandidates)
            this.candidateVisible = true
          } else {
            if (this.properties.isCustomCopy) {
              this.branchList = []
              this.candidateList = []
              this.candidateVisible = true
              return
            }
            this.$confirm('您确定要提交当前流程吗, 是否继续?', '提示', {
              type: 'warning'
            }).then(() => {
              this.handleRequest()
            }).catch(() => { });
          }
        }).catch(() => {
          this.candidateLoading = false
        })
      },
      handleRequest(candidateData) {
        if (candidateData) this.formData = { ...this.formData, ...candidateData }
        this.formData.candidateType = this.candidateType
        this.formData.countersignOver = this.countersignOver
        if (!this.formData.id) delete (this.formData.id)
        if (this.eventType === 'save') this.btnLoading = true
        this.allBtnDisabled = true
        const formMethod = this.formData.id ? Update : Create
        formMethod(this.formData).then(res => {
          const errorData = res.data
          if (errorData && Array.isArray(errorData) && errorData.length) {
            this.errorNodeList = errorData
            this.errorVisible = true
            this.allBtnDisabled = false
          } else {
            this.$message({
              message: res.msg,
              type: 'success',
              duration: 1500,
              onClose: () => {
                if (this.eventType === 'save') this.btnLoading = false
                this.candidateVisible = false
                this.allBtnDisabled = false
                this.errorVisible = false
                this.$emit('close', true)
              }
            })
          }
        }).catch(() => {
          if (this.eventType === 'save') this.btnLoading = false
          if (this.$refs.candidateForm) this.$refs.candidateForm.btnLoading = false
          this.allBtnDisabled = false
          this.errorVisible = false
        })
      },
      submitCandidate(data) {
        this.handleRequest(data)
      },
      actionLauncher(eventType) {
        this.eventType = eventType
        if (['shareEx'].includes(eventType)) {
          let title = '';
          if (eventType == 'shareEx') title = '此是关注/取关操作，是否继续？';
          this.$confirm(title, '提示', {
            type: 'warning'
          }).then(() => {
            this.actionReceiver()
          }).catch(() => { });
          return
        }
        else if (['revoke', 'recall', 'approvalCancel', 'counterSignAbstention', 'lockOrUnLock'].includes(eventType) && !this.properties.hasOpinion && !this.properties.hasSign) {
          let title = '';
          if (eventType == 'revoke') title = '此操作将撤回该流程，是否继续？';
          if (eventType == 'recall') title = '此操作将撤回该审批单，是否继续？';
          if (eventType == 'approvalCancel') title = '此是不同意操作,并不会驳回到其他节点，是否继续？';
          if (eventType == 'counterSignAbstention') title = '此是弃权操作,并不会跳转到其他节点，是否继续？';
          if (eventType == 'lockOrUnLock') title = '此是锁定/解锁操作,并不会跳转到其他节点，是否继续？';
          this.$confirm(title, '提示', {
            type: 'warning'
          }).then(() => {
            this.actionReceiver()
          }).catch(() => { });
          return
        }
        this.showActionDialog()
      },
      showActionDialog() {
        this.actionVisible = true
        this.$nextTick(() => {
          this.$refs.actionDialog.init(this.properties, this.eventType)
        })
      },
      actionReceiver(query) {
        if (!query) {
          query = {
            handleOpinion: '',
            signImg: '',
            fileList: []
          }
        }
        if (this.isIframeForm) {
          query = {
            ...query,
            formData: this.flowDataObj.formData
          }
        }
        if (this.eventType == 'approvalCancel') query = { ...query, eventType: "approvalCancel" }
        if (this.eventType == 'counterSignAbstention') query = { ...query, eventType: "counterSignAbstention" }
        if (this.eventType == 'lockOrUnLock') query = { ...query, eventType: "lockOrUnLock" }
        if (this.eventType == 'shareEx') query = { ...query, eventType: "shareEx" }
        const id = this.eventType == 'revoke' || this.eventType == 'approvalCancel' || this.eventType == 'counterSignAbstention' || this.eventType == 'lockOrUnLock' || this.eventType == 'shareEx' || this.eventType == 'ccBatch' ? this.setting.id : this.setting.taskId
        const actionMethod = this.getActionMethod()
        this.approvalBtnLoading = true
        actionMethod(id, query).then(res => {
          this.approvalBtnLoading = false
          this.$message({
            type: 'success',
            message: res.msg,
            duration: 1000,
            onClose: () => {
              this.$emit('close', true)
            }
          })
        }).catch(() => {
          this.$refs.actionDialog.btnLoading = false
          this.approvalBtnLoading = false
        })
      },
      getActionMethod() {
        if (this.eventType === 'transfer') return Transfer
        if (this.eventType === 'invoke') return Invoke
        if (this.eventType === 'multiAdd') return MultiAdd
        if (this.eventType === 'specialJump') return SpecialJump
        if (this.eventType === 'shareEx') return ShareEx
        if (this.eventType === 'assist') return Assist
        if (this.eventType === 'cc') return Cc
        if (this.eventType === 'ccBatch') return CcBatch
        if (this.eventType === 'taskCancel') return TaskCancel
        if (this.eventType === 'assign') return Assign
        if (this.eventType === 'revoke') return Revoke
        if (this.eventType === 'recall') return Recall
        if (this.eventType === 'cancel') return Cancel
        if (this.eventType === 'approvalCancel') return ApprovalCancel;
        if (this.eventType === 'counterSignAbstention') return CounterSignAbstention;
        if (this.eventType === 'lockOrUnLock') return LockOrUnLock;
      },
      press() {
        this.$confirm('此操作将提示该节点尽快处理，是否继续?', '提示', {
          type: 'warning'
        }).then(() => {
          Press(this.setting.id).then(res => {
            this.$message({
              type: 'success',
              message: res.msg,
              duration: 1000
            })
          })
        }).catch(() => { })
      },
      handleError(data) {
        if (this.eventType === 'submit') {
          this.formData.errorRuleUserList = data
          this.handleRequest()
          return
        }
        if (this.eventType === 'audit' || this.eventType === 'reject') {
          this.handleApproval(data)
          return
        }
        if (this.eventType === 'resurgence') {
          this.handleResurgence(data)
          return
        }
      },
      handleApproval(errorRuleUserList) {
        const handleRequest = () => {
          let query = {
            handleOpinion: this.candidateForm.handleOpinion,
            fileList: this.candidateForm.fileList,
            ...this.formData,
            enCode: this.setting.enCode,
            signImg: this.candidateForm.signImg,
            copyIds: this.copyIds.join(','),
            branchList: this.candidateForm.branchList,
            candidateType: this.candidateType,
            countersignOver: this.countersignOver,
            rejectType: this.candidateForm.rejectType
          }
          if (this.eventType === 'reject') query.rejectStep = this.candidateForm.rejectStep
          if (errorRuleUserList) query.errorRuleUserList = errorRuleUserList
          if (this.candidateForm.candidateList.length) {
            let candidateList = {}
            for (let i = 0; i < this.candidateForm.candidateList.length; i++) {
              candidateList[this.candidateForm.candidateList[i].nodeId] = this.candidateForm.candidateList[i].value
            }
            query.candidateList = candidateList
          }
          if (this.eventType === 'audit' && this.properties.hasFreeApprover) {
            query = { freeApproverUserId: this.handleId, ...query }
          }
          const approvalMethod = this.eventType === 'audit' ? Audit : Reject
          this.approvalBtnLoading = true
          approvalMethod(this.setting.taskId, query).then(res => {
            const errorData = res.data
            if (errorData && Array.isArray(errorData) && errorData.length) {
              this.errorNodeList = errorData
              this.errorVisible = true
              this.approvalBtnLoading = false
            } else {
              this.$message({
                type: 'success',
                message: res.msg,
                duration: 1000,
                onClose: () => {
                  this.approvalBtnLoading = false;
                  this.visible = false;
                  this.errorVisible = false;
                  if (this.isFromOaJump) {
                    // 关闭OA的iframe
                    window.parent.postMessage({
                      closed: true
                    }, '\*');
                    window.close();
                  } else {
                    this.$emit('close', true)
                  }
                }
              })
            }
          }).catch(() => { this.approvalBtnLoading = false })
        }
        if (!this.isValidate) return handleRequest()
        this.$refs['candidateForm'].validate((valid) => {
          if (valid) {
            handleRequest()
          }
        })
      },
      setPageLoad(val) {
        this.loading = !!val
      },
      setCandidateLoad(val) {
        this.candidateLoading = !!val
        this.allBtnDisabled = !!val
      },
      setLoad(val) {
        this.btnLoading = !!val
      },
      handleFlowUrgent(e) {
        this.flowUrgent = e
      }
    }
  }
</script>
<style lang="scss" scoped>
  .flow-form-main {
    .JNPF-el_tabs {
      // height: calc(100% - 62px);
    }
  }

  .color-box {
    width: 7px;
    height: 7px;
    display: inline-block;
    border-radius: 50%;
  }
  .flow-urgent-value {
    display: flex;
    align-items: center;
    span:first-child {
      margin: 0 3px 0 10px;
    }
  }

  .options {
    .dropdown {
      margin-right: 10px;
    }
    .el-button {
      min-width: 70px;
    }
  }
  .dropdown-item {
    min-width: 70px;
    text-align: center;
  }
  .subFlow_tabs {
    // ::v-deep .el-tabs__item {
    //   text-align: center;
    // }
    // ::v-deep .el-tabs__content {
    //   padding: 0px 0 15px;
    // }
    height: 100%;
    overflow: auto;
    overflow-x: hidden;
    /* padding: 0 10px 10px; */
  }
  .commonWords-button {
    margin-top: 57px;
  }
  .JNPF-page-header-content {
    max-width: 40vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .jnpf-common-form-wrapper {
    height: 100%;
    overflow: hidden;
    display: flex;
    .jnpf-common-form-wrapper__main {
      flex: 1;
      flex-shrink: 0;
      overflow: auto;
      position: relative;
    }
  }
</style>
